Load required libraries
library(tidyverse)
library(here)
library(brms)
library(tidybayes)
library(sf)
library(mgcv)
library(priorsense)
library(osmdata)
library(nngeo)
Air quality data
By summary, a random household survey was conducted in Blantyre
Malawi during 2019-2020 (pre-COVID in Malawi) as part of a TB cluster
randomised trial pre-intervention prevalence survey (sumamrised here: https://europepmc.org/article/MED/37862284).
Fieldworkers carried purple air monitors attached to their backpacks,
with measurements set to read every 90 seconds. Not all fieldworkers had
a monitor. Previously, Helen Savage cleaned these monitor data, and
merged to household questionnaire data, filtering measurements by
interview times. Therefore, measurements are indoor household
measurements.
Cluster boundaries (72 in total) are based on Ministry of Health
Community Health Worker catchment areas, refined in collaboration with
researchers. These were the unit of randomisation for the SCALE cluster
randomised trial.
All air quality measurements were then taken from households within
the 72 SCALE cluster.
load("input_data/aq_in.RData")
#input the scale clusters
load("input_data/scale_72_clusters.rda")
Get data into correct shape and aggregate measurements per household.
Note as purple air devices took measurements every 90 seconds, mostly
housholds surveyed have multiple measurements. Here, for convenience, we
take the mean of these measurement per household.

Covariates
Population counts and density
#fix the coordinate crs of the scale clusters
scale_72_clusters <- st_transform(scale_72_clusters, st_crs(mw_100m))
old-style crs object detected; please recreate object with a recent sf::st_crs()
Building density (i.e. we get the building footprints, and calculate
their combined footprint area per grid cell, then calculate what
percentage of the grid cell is “building footprint”) https://sites.research.google/gr/open-buildings/#open-buildings-download
Using Version 2 here - can update later to V3, with better precision,
and year-specific data. (I think this is for 2020 currently)
#read in the data set
#is a stars dataset
buildings <- read_rds("input_data/blantyre_buff_buildings.rds")
#match the crs to the population data
buildings <- st_transform(buildings, st_crs(mw_100m))
#convert stars object to polygons
mw_100m_grid_sf <- st_as_sf(mw_100m_cropped, as_points = FALSE, merge = FALSE)
#add grid cell ID for grouping
mw_100m_grid_sf <- mw_100m_grid_sf %>%
mutate(grid_id = row_number())
#join building footprint data to the population data
buildings_with_grid <- st_join(buildings, mw_100m_grid_sf, left = FALSE)
#filter by confidence of building footprint, and by footprint size
#in Hannah R's previous experiements, this was a good compromise
#and matches well with home visits on the ground.
buildings_with_grid <- buildings_with_grid %>%
filter(area_in_meters>20) %>%
filter(area_in_meters<300) %>%
filter(confidence>0.69)
#sum building footprint per grid cell
building_area_per_cell <- buildings_with_grid %>%
group_by(grid_id) %>%
summarise(total_building_area_m2 = sum(area_in_meters, na.rm = TRUE))
#cell area in m squared
cell_area_m2 <- 100 * 100
#compute percentage coverage
building_area_per_cell <- building_area_per_cell %>%
mutate(building_coverage_pct = (total_building_area_m2 / cell_area_m2) * 100)
#join
mw_100m_grid_sf <- mw_100m_grid_sf %>%
left_join(building_area_per_cell %>% st_drop_geometry(), by = "grid_id") %>%
mutate(building_coverage_pct = replace_na(building_coverage_pct, 0))
#check by plotting
mw_100m_grid_sf %>%
mutate(x = st_coordinates(st_centroid(.))[, 1],
y = st_coordinates(st_centroid(.))[, 2]) %>%
ggplot() +
geom_tile(aes(x=x, y=y, fill=building_coverage_pct)) +
scale_fill_viridis_c(option = "cividis") +
theme_ggdist() +
theme(panel.background = element_rect(colour = "grey78"))
Distance to the nearest main road. I.e. because we think that PM2.5
exposure can come from road vehicles.
We use Open Street Map (OSM) data to get the main roads (there are
few of these in Blantyre… but see the most traffic). Later could
consider including some smaller road…
#check plot
mw_100m_grid_sf %>%
mutate(x = st_coordinates(st_centroid(.))[, 1],
y = st_coordinates(st_centroid(.))[, 2]) %>%
ggplot() +
geom_tile(aes(x=x, y=y, fill=dist_to_road_m)) +
scale_fill_viridis_c(option = "G", direction = -1) +
theme(panel.background = element_rect(colour = "grey78")) +
theme_ggdist() +
theme(panel.background = element_rect(colour = "grey78"))
Warning: There were 2 warnings in `stopifnot()`.
The first warning was:
ℹ In argument: `x = st_coordinates(st_centroid(.))[, 1]`.
Caused by warning:
! st_centroid assumes attributes are constant over geometries
ℹ Run ]8;;ide:run:dplyr::last_dplyr_warnings()dplyr::last_dplyr_warnings()]8;; to see the 1 remaining warning.

Join all together into the modelling dataset, and just last
tidy-up.
# Convert aq_data to sf object
aq_model_data <- st_as_sf(aq_model_data, coords = c("x", "y"), crs = st_crs(mw_100m_cropped))
aq_model_data <- st_transform(aq_model_data, st_crs(mw_100m_cropped))
aq_model_data <- st_join(aq_model_data, mw_100m_grid_sf)
aq_model_data <- aq_model_data %>%
mutate(x = st_coordinates(st_centroid(.))[, 1],
y = st_coordinates(st_centroid(.))[, 2]) %>%
st_drop_geometry() %>%
mutate(building_coverage_pct = building_coverage_pct/100)
aq_model_data <- aq_model_data %>%
mutate(building_coverage_pct_z = scale(.$building_coverage_pct)[,1])
Model 1:
“We fitted a spatially smooth regression model for log-transformed
PM2.5 concentrations using a Gaussian process (GP) smooth over spatial
coordinates (x, y) to capture flexible spatial trends. Seasonal
variation was modelled using a Fourier series expansion of day-of-year
up to the 3rd harmonic (i.e., sine and cosine terms for annual,
semi-annual, and tri-annual cycles) to account for complex seasonal
patterns. The model was fitted in a Bayesian framework using brms with a
Gaussian likelihood and the cmdstanr backend.”
Note, priors are still causing issues for me, so we will comment out
now, and use the defauly stan weakly informative priors
Priors
priors <- c(
prior(normal(3.4, 1), class = "Intercept"), # Weakly informative on log_pm2_5
prior(exponential(1), class = "sdgp"), # GP standard deviation prior
#prior(student_t(3, 0, 5.9), class = "sds"), # Smooth term std dev prior (key!)
prior(exponential(1), class = "sigma"), # Observation error
prior(normal(0,10), class = "b")
)
Fit prior only model



Now model with data.



Compare prior-only model to model with data using
priorsense package:
# m1_draws <- as_draws_df(m1)
#
# # Extract prior and posterior draws
# powerscale_sensitivity(m1, variable = c("b_Intercept", "b_sin_doy", "b_cos_doy",
# "sdgp_gpxy", "sigma", "Intercept"))
#
# powerscale_plot_dens(m1, variable = c("b_Intercept", "b_sin_doy", "b_cos_doy",
# "sdgp_gpxy", "sigma", "Intercept"))
Predictions by space and time. Here, although we only have data
within clusters, we will predict for cells outside of clusters based on
covariates. We will also predict for the month for whcih we do not have
data.

Now just draw 50 random coordinates, and predict by time to see
whether we captured the trend.

Model 2: With covariates
Now we include grid level covariates of distance to the road,
population density, and building footprint percent, along witht the mean
temp and huidity on the day of measurement (from the purple air
monitors)
Again, priors to be fixed later














Predictions by space and time

Sample coordinates, and plot over time

Compare models, using LOO CV
loo_compare(loo_m1, loo_m2)
elpd_diff se_diff
m2 0.0 0.0
m1 -115.8 18.6
TODO
- PRIORS
- OTHER COVARIATES
- COMPARE MODELS WITH DIFFERENT BASIS FUNCTIONS FOR GP AND
SPLINES
- EXCEEDANCES
- LINK TO MTB INFECTION PREVALENCE DATA, AND MODEL
LS0tCnRpdGxlOiAiQmxhbnR5cmUgYWlyIHF1YWxpdHkgbW9kZWxsaW5nIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpMb2FkIHJlcXVpcmVkIGxpYnJhcmllcwoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkoYnJtcykKbGlicmFyeSh0aWR5YmF5ZXMpCmxpYnJhcnkoc2YpCmxpYnJhcnkobWdjdikKbGlicmFyeShwcmlvcnNlbnNlKQpsaWJyYXJ5KG9zbWRhdGEpCmxpYnJhcnkobm5nZW8pIApgYGAKCgojIyMgQWlyIHF1YWxpdHkgZGF0YQoKQnkgc3VtbWFyeSwgYSByYW5kb20gaG91c2Vob2xkIHN1cnZleSB3YXMgY29uZHVjdGVkIGluIEJsYW50eXJlIE1hbGF3aSBkdXJpbmcgMjAxOS0yMDIwIChwcmUtQ09WSUQgaW4gTWFsYXdpKSBhcyBwYXJ0IG9mIGEgVEIgY2x1c3RlciByYW5kb21pc2VkIHRyaWFsICBwcmUtaW50ZXJ2ZW50aW9uIHByZXZhbGVuY2Ugc3VydmV5IChzdW1hbXJpc2VkIGhlcmU6IGh0dHBzOi8vZXVyb3BlcG1jLm9yZy9hcnRpY2xlL01FRC8zNzg2MjI4NCkuIEZpZWxkd29ya2VycyBjYXJyaWVkIHB1cnBsZSBhaXIgbW9uaXRvcnMgYXR0YWNoZWQgdG8gdGhlaXIgYmFja3BhY2tzLCB3aXRoIG1lYXN1cmVtZW50cyBzZXQgdG8gcmVhZCBldmVyeSA5MCBzZWNvbmRzLiBOb3QgYWxsIGZpZWxkd29ya2VycyBoYWQgYSBtb25pdG9yLiBQcmV2aW91c2x5LCBIZWxlbiBTYXZhZ2UgY2xlYW5lZCB0aGVzZSBtb25pdG9yIGRhdGEsIGFuZCBtZXJnZWQgdG8gaG91c2Vob2xkIHF1ZXN0aW9ubmFpcmUgZGF0YSwgZmlsdGVyaW5nIG1lYXN1cmVtZW50cyBieSBpbnRlcnZpZXcgdGltZXMuIFRoZXJlZm9yZSwgbWVhc3VyZW1lbnRzIGFyZSBpbmRvb3IgaG91c2Vob2xkIG1lYXN1cmVtZW50cy4KCkNsdXN0ZXIgYm91bmRhcmllcyAoNzIgaW4gdG90YWwpIGFyZSBiYXNlZCBvbiBNaW5pc3RyeSBvZiBIZWFsdGggQ29tbXVuaXR5IEhlYWx0aCBXb3JrZXIgY2F0Y2htZW50IGFyZWFzLCByZWZpbmVkIGluIGNvbGxhYm9yYXRpb24gd2l0aCByZXNlYXJjaGVycy4gVGhlc2Ugd2VyZSB0aGUgdW5pdCBvZiByYW5kb21pc2F0aW9uIGZvciB0aGUgU0NBTEUgY2x1c3RlciByYW5kb21pc2VkIHRyaWFsLgoKQWxsIGFpciBxdWFsaXR5IG1lYXN1cmVtZW50cyB3ZXJlIHRoZW4gdGFrZW4gZnJvbSBob3VzZWhvbGRzIHdpdGhpbiB0aGUgNzIgU0NBTEUgY2x1c3Rlci4KCmBgYHtyfQpsb2FkKCJpbnB1dF9kYXRhL2FxX2luLlJEYXRhIikgI2NsZWFuZWQgYWlyLXF1YWxpdHkgZGF0YXNldApsb2FkKCJpbnB1dF9kYXRhL3NjYWxlXzcyX2NsdXN0ZXJzLnJkYSIpICNTQ0FMRSBjbHVzdGVycwpgYGAKCkdldCBkYXRhIGludG8gY29ycmVjdCBzaGFwZSBhbmQgYWdncmVnYXRlIG1lYXN1cmVtZW50cyBwZXIgaG91c2Vob2xkLiBOb3RlIGFzIHB1cnBsZSBhaXIgZGV2aWNlcyB0b29rIG1lYXN1cmVtZW50cyBldmVyeSA5MCBzZWNvbmRzLCBtb3N0bHkgaG91c2hvbGRzIHN1cnZleWVkIGhhdmUgbXVsdGlwbGUgbWVhc3VyZW1lbnRzLiBIZXJlLCBmb3IgY29udmVuaWVuY2UsIHdlIHRha2UgdGhlIG1lYW4gb2YgdGhlc2UgbWVhc3VyZW1lbnQgcGVyIGhvdXNlaG9sZC4KCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CmFxX2RhdCA8LSBhcV9pbiAlPiUKICBzZWxlY3QoZGF0ZXRpbWUsIGgwMmNsX2lkLCBoaF9pZCwgaGhfbGF0LCBoaF9sb24sIHRlbXBfYywgY3VycmVudF9odW1pZGl0eSwgbWVhbl9wbV8yXzUsIGRpc3RhbmNlX2ttKSAlPiUKIG11dGF0ZSgKICAgZGF0ZXRpbWUgPSB5bWRfaG1zKGRhdGV0aW1lKSwKICAgaG91ciA9IGhvdXIoZGF0ZXRpbWUpICsgbWludXRlKGRhdGV0aW1lKS82MCwKICAgZG95ID0geWRheShkYXRldGltZSksCiAgIHggPSBoaF9sb24sCiAgIHkgPSBoaF9sYXQpICU+JQogIGdyb3VwX2J5KGhoX2lkKSAlPiUKICByZWZyYW1lKGgwMmNsX2lkID0gaDAyY2xfaWQsCiAgICAgICAgICB4ID0geCwKICAgICAgICAgIHkgPSB5LAogICAgICAgICAgbWVhbl9kb3kgPSBtZWFuKGRveSwgbmEucm09VFJVRSksCiAgICAgICAgICBtZWFuX3BtMl81ID0gbWVhbihtZWFuX3BtXzJfNSksIAogICAgICAgICAgbWVhbl90ZW1wX2MgPSBtZWFuKHRlbXBfYywgbmEucm09VFJVRSksCiAgICAgICAgICBtZWFuX2N1cnJlbnRfaHVtaWRpdHkgPSBtZWFuKGN1cnJlbnRfaHVtaWRpdHksIG5hLnJtPVRSVUUpKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIG11dGF0ZShsb2dfcG0yXzUgPSBsb2cobWVhbl9wbTJfNSkpCgoKI3dlIHdpbGwgdXNlIEZvdXJpZXIgc2VyaWVzIGNvbXBvbmVudHMgd2l0aCBtdWx0aXBsZSBoYXJtb25pY3MgdG8gbW9kZWwgZGF5LW9mLXRoZSB5ZWFyIGVmZmVjdHMKYXFfZGF0IDwtIGFxX2RhdCAlPiUKICBtdXRhdGUoCiAgICBzaW5fZG95MSA9IHNpbigyICogcGkgKiBtZWFuX2RveSAvIDM2NSksCiAgICBjb3NfZG95MSA9IGNvcygyICogcGkgKiBtZWFuX2RveSAvIDM2NSksCiAgICBzaW5fZG95MiA9IHNpbig0ICogcGkgKiBtZWFuX2RveSAvIDM2NSksCiAgICBjb3NfZG95MiA9IGNvcyg0ICogcGkgKiBtZWFuX2RveSAvIDM2NSksCiAgICBzaW5fZG95MyA9IHNpbig2ICogcGkgKiBtZWFuX2RveSAvIDM2NSksCiAgICBjb3NfZG95MyA9IGNvcyg2ICogcGkgKiBtZWFuX2RveSAvIDM2NSkKICApCgojY2hlY2sgc29tZSB2YXJpYWJsZXMKYXFfZGF0ICU+JQogIHNlbGVjdChoaF9pZCwgbG9nX3BtMl81LCBtZWFuX3RlbXBfYywgbWVhbl9jdXJyZW50X2h1bWlkaXR5LCBtZWFuX2RveSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGxvZ19wbTJfNSwgbWVhbl90ZW1wX2MsIG1lYW5fY3VycmVudF9odW1pZGl0eSwgbWVhbl9kb3kpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHg9dmFsdWUsIGZpbGw9bmFtZSkpICsKICBmYWNldF93cmFwKG5hbWV+Liwgc2NhbGVzID0gImZyZWVfeCIpCgojUE0yLjUgZGlzdHJpYnV0aW9uIGJ5IGRheSBvZiB0aGUgeWVhcgphcV9kYXQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21faml0dGVyKGFlcyh4ID0gbWVhbl9kb3ksIHk9bG9nX3BtMl81KSwgY29sb3VyPSJkYXJrcmVkIiwgYWxwaGE9MC41KSArCiAgdGhlbWVfZ2dkaXN0KCkgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyPSJncmV5NzgiKSkKI05vdGUgdGhhdCB0aGVyZSB3YXMgbm8gZGF0YSBjb2xsZWN0aW9uIGluIEFwcmlsIG9mIGVpdGhlciB5ZWFyCgoKI3Bsb3QgdGhlIG1lYXN1cmVtZW50cyBvbiBhIG1hcAphcV9kYXQgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YT1zY2FsZV83Ml9jbHVzdGVycywgZmlsbD1OQSkgKwogIGdlb21fcG9pbnQoYWVzKHg9eCwgeT15LCBjb2xvdXI9bG9nX3BtMl81KSwgc2l6ZT0wLjEpKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfYygpICsKICB0aGVtZV9nZ2Rpc3QoKSArCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXI9ImdyZXk3OCIpKSAKCiNOb3RlIHRoZSB3YXJuaW5nIGFib3V0IG9sZCBjb29yZGluYXRlIHJlZmVyZW5jZSBzeXN0ZW0gLSB3ZSB3aWxsIGZpeCB0aGlzIGJlbG93LgoKYGBgCgojIyMgQ292YXJpYXRlcwoKUG9wdWxhdGlvbiBjb3VudHMgYW5kIGRlbnNpdHkKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CgojcmVhZCBpbiB0aGUgLnRpZmYgaW1hZ2Ugb2YgcG9wdWxhdGlvbiBjb3VudCBmcm9tIFdvcmxkcG9wCiNodHRwczovL2h1Yi53b3JsZHBvcC5vcmcvZ2VvZGF0YS9zdW1tYXJ5P2lkPTE1NjAKbXdfMTAwbSA8LSBzdGFyczo6cmVhZF9zdGFycygiaW5wdXRfZGF0YS9td2lfcHBwXzIwMjAudGlmIikKCgojZGVmaW5lIGJ1ZmZlciBhcm91bmQKYnVmZmVyX20gPC0gNTAwCgojYXBwcm94aW1hdGUgY29udmVyc2lvbiBmYWN0b3IgKGRlZ3JlZXMgcGVyIG1ldGVyKQojYWRqdXN0IGZvciBsYXRpdHVkZSBmb3IgbG9uZ2l0dWRlIGRpcmVjdGlvbgpsYXRfbWVhbiA8LSBtZWFuKGFxX2RhdCR5KQpkZWdfcGVyX21fbGF0IDwtIDEgLyAxMTEzMjAgICMgUm91Z2ggY29udmVyc2lvbiBmb3IgbGF0aXR1ZGUKZGVnX3Blcl9tX2xvbiA8LSAxIC8gKDExMTMyMCAqIGNvc3BpKGxhdF9tZWFuIC8gMTgwKSkgICMgQWRqdXN0IGZvciBsYXRpdHVkZQoKI2V4cGFuZGJvdW5kaW5nIGJveCB3aXRoIGJ1ZmZlcgpiYm94X2J1ZmZlcmVkIDwtIHN0X2Jib3goYygKICB4bWluID0gbWluKGFxX2RhdCR4KSAtIGJ1ZmZlcl9tICogZGVnX3Blcl9tX2xvbiwKICB4bWF4ID0gbWF4KGFxX2RhdCR4KSArIGJ1ZmZlcl9tICogZGVnX3Blcl9tX2xvbiwKICB5bWluID0gbWluKGFxX2RhdCR5KSAtIGJ1ZmZlcl9tICogZGVnX3Blcl9tX2xhdCwKICB5bWF4ID0gbWF4KGFxX2RhdCR5KSArIGJ1ZmZlcl9tICogZGVnX3Blcl9tX2xhdAopLCBjcnMgPSBzdF9jcnMobXdfMTAwbSkpCgojY3JvcCB3b3JsZHBvcCByYXN0ZXIgdG8gYnVmZmVyZWQgYmJveAptd18xMDBtX2Nyb3BwZWQgPC0gc3RfY3JvcChtd18xMDBtLCBiYm94X2J1ZmZlcmVkKQoKI3Bsb3QKcGxvdChtd18xMDBtX2Nyb3BwZWQpCgoKI3RoZXJlIGFyZSBhIHNtYWxsIG51bWJlciBvZiBjZWxscyBpbiB0aGUgY2VudHJlIHRoYXQgYXJlIE5BCiNJIHRoaW5rIHRoZXNlIGFyZSB0aGUgbWlsaXRhcnkgcmFkYXIgb24gTW91bnQgU29jaGUsCiNzbyBubyBleHBlY3RlZCBwb3B1bGF0aW9uCiNyZXBsYWNlIHdpdGggMAptd18xMDBtX2Nyb3BwZWRbWzFdXVtpcy5uYShtd18xMDBtX2Nyb3BwZWRbWzFdXSldIDwtIDAKCiNkaWQgaXQgd29yaz8KcGxvdChtd18xMDBtX2Nyb3BwZWQpCgojeG9udmVydCB0byBzZiBvYmplY3QKYXFfc2YgPC0gc3RfYXNfc2YoYXFfZGF0LCBjb29yZHMgPSBjKCJ4IiwgInkiKSwgY3JzID0gc3RfY3JzKG13XzEwMG1fY3JvcHBlZCkpCgojbWVyZ2Ugd2l0aCB0aGUgcG9wdWxhdGlvbiBjb3VudCBkYXRhCmFxX3NmJHBvcF9kZW5zaXR5IDwtIHN0YXJzOjpzdF9leHRyYWN0KG13XzEwMG1fY3JvcHBlZCwgYXFfc2YpW1sxXV0KCiNnZXQgcG9wdWxhdGlvbiBkZW5zaXR5CmFxX21vZGVsX2RhdGEgPC0gYXFfc2YgJT4lCiAgc3RfZHJvcF9nZW9tZXRyeSgpICU+JQogIGFzX3RpYmJsZSgpICU+JQogIG11dGF0ZShwb3BfZGVuc2l0eV9rbTIgPSBwb3BfZGVuc2l0eSAvIDAuMDEpICU+JQogIGxlZnRfam9pbihhcV9kYXQgJT4lIHNlbGVjdChoaF9pZCwgeCwgeSkpCgojZml4IHRoZSBjb29yZGluYXRlIGNycyBvZiB0aGUgc2NhbGUgY2x1c3RlcnMKc2NhbGVfNzJfY2x1c3RlcnMgPC0gIHN0X3RyYW5zZm9ybShzY2FsZV83Ml9jbHVzdGVycywgc3RfY3JzKG13XzEwMG0pKQoKYGBgCgpCdWlsZGluZyBkZW5zaXR5IChpLmUuIHdlIGdldCB0aGUgYnVpbGRpbmcgZm9vdHByaW50cywgYW5kIGNhbGN1bGF0ZSB0aGVpciBjb21iaW5lZCBmb290cHJpbnQgYXJlYSBwZXIgZ3JpZCBjZWxsLCB0aGVuIGNhbGN1bGF0ZSB3aGF0IHBlcmNlbnRhZ2Ugb2YgdGhlIGdyaWQgY2VsbCBpcyAiYnVpbGRpbmcgZm9vdHByaW50IikKaHR0cHM6Ly9zaXRlcy5yZXNlYXJjaC5nb29nbGUvZ3Ivb3Blbi1idWlsZGluZ3MvI29wZW4tYnVpbGRpbmdzLWRvd25sb2FkIAoKVXNpbmcgVmVyc2lvbiAyIGhlcmUgLSBjYW4gdXBkYXRlIGxhdGVyIHRvIFYzLCB3aXRoIGJldHRlciBwcmVjaXNpb24sIGFuZCB5ZWFyLXNwZWNpZmljIGRhdGEuIChJIHRoaW5rIHRoaXMgaXMgZm9yIDIwMjAgY3VycmVudGx5KQoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KCiNyZWFkIGluIHRoZSBkYXRhIHNldAojaXMgYSBzdGFycyBkYXRhc2V0CmJ1aWxkaW5ncyA8LSByZWFkX3JkcygiaW5wdXRfZGF0YS9ibGFudHlyZV9idWZmX2J1aWxkaW5ncy5yZHMiKQoKI21hdGNoIHRoZSBjcnMgdG8gdGhlIHBvcHVsYXRpb24gZGF0YQpidWlsZGluZ3MgPC0gIHN0X3RyYW5zZm9ybShidWlsZGluZ3MsIHN0X2Nycyhtd18xMDBtKSkKCiNjb252ZXJ0IHN0YXJzIG9iamVjdCB0byBwb2x5Z29ucwptd18xMDBtX2dyaWRfc2YgPC0gc3RfYXNfc2YobXdfMTAwbV9jcm9wcGVkLCBhc19wb2ludHMgPSBGQUxTRSwgbWVyZ2UgPSBGQUxTRSkKCiNhZGQgZ3JpZCBjZWxsIElEIGZvciBncm91cGluZwptd18xMDBtX2dyaWRfc2YgPC0gbXdfMTAwbV9ncmlkX3NmICU+JQogIG11dGF0ZShncmlkX2lkID0gcm93X251bWJlcigpKQoKI2pvaW4gYnVpbGRpbmcgZm9vdHByaW50IGRhdGEgdG8gdGhlIHBvcHVsYXRpb24gZGF0YQpidWlsZGluZ3Nfd2l0aF9ncmlkIDwtIHN0X2pvaW4oYnVpbGRpbmdzLCBtd18xMDBtX2dyaWRfc2YsIGxlZnQgPSBGQUxTRSkKCiNmaWx0ZXIgYnkgY29uZmlkZW5jZSBvZiBidWlsZGluZyBmb290cHJpbnQsIGFuZCBieSBmb290cHJpbnQgc2l6ZQojaW4gSGFubmFoIFIncyBwcmV2aW91cyBleHBlcmllbWVudHMsIHRoaXMgd2FzIGEgZ29vZCBjb21wcm9taXNlCiNhbmQgbWF0Y2hlcyB3ZWxsIHdpdGggaG9tZSB2aXNpdHMgb24gdGhlIGdyb3VuZC4KYnVpbGRpbmdzX3dpdGhfZ3JpZCA8LSBidWlsZGluZ3Nfd2l0aF9ncmlkICU+JQogIGZpbHRlcihhcmVhX2luX21ldGVycz4yMCkgJT4lCiAgZmlsdGVyKGFyZWFfaW5fbWV0ZXJzPDMwMCkgJT4lCiAgZmlsdGVyKGNvbmZpZGVuY2U+MC42OSkKCiNzdW0gYnVpbGRpbmcgZm9vdHByaW50IHBlciBncmlkIGNlbGwKYnVpbGRpbmdfYXJlYV9wZXJfY2VsbCA8LSBidWlsZGluZ3Nfd2l0aF9ncmlkICU+JQogIGdyb3VwX2J5KGdyaWRfaWQpICU+JQogIHN1bW1hcmlzZSh0b3RhbF9idWlsZGluZ19hcmVhX20yID0gc3VtKGFyZWFfaW5fbWV0ZXJzLCBuYS5ybSA9IFRSVUUpKQoKI2NlbGwgYXJlYSBpbiBtIHNxdWFyZWQKY2VsbF9hcmVhX20yIDwtIDEwMCAqIDEwMAoKI2NvbXB1dGUgcGVyY2VudGFnZSBjb3ZlcmFnZQpidWlsZGluZ19hcmVhX3Blcl9jZWxsIDwtIGJ1aWxkaW5nX2FyZWFfcGVyX2NlbGwgJT4lCiAgbXV0YXRlKGJ1aWxkaW5nX2NvdmVyYWdlX3BjdCA9ICh0b3RhbF9idWlsZGluZ19hcmVhX20yIC8gY2VsbF9hcmVhX20yKSAqIDEwMCkKCiNqb2luCm13XzEwMG1fZ3JpZF9zZiA8LSBtd18xMDBtX2dyaWRfc2YgJT4lCiAgbGVmdF9qb2luKGJ1aWxkaW5nX2FyZWFfcGVyX2NlbGwgJT4lIHN0X2Ryb3BfZ2VvbWV0cnkoKSwgYnkgPSAiZ3JpZF9pZCIpICU+JQogIG11dGF0ZShidWlsZGluZ19jb3ZlcmFnZV9wY3QgPSByZXBsYWNlX25hKGJ1aWxkaW5nX2NvdmVyYWdlX3BjdCwgMCkpCgojY2hlY2sgYnkgcGxvdHRpbmcKbXdfMTAwbV9ncmlkX3NmICU+JQogIG11dGF0ZSh4ID0gc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoLikpWywgMV0sCiAgICAgICAgIHkgPSBzdF9jb29yZGluYXRlcyhzdF9jZW50cm9pZCguKSlbLCAyXSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fdGlsZShhZXMoeD14LCB5PXksIGZpbGw9YnVpbGRpbmdfY292ZXJhZ2VfcGN0KSkgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJjaXZpZGlzIikgKwogIHRoZW1lX2dnZGlzdCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJncmV5NzgiKSkKCmBgYAoKRGlzdGFuY2UgdG8gdGhlIG5lYXJlc3QgbWFpbiByb2FkLiBJLmUuIGJlY2F1c2Ugd2UgdGhpbmsgdGhhdCBQTTIuNSBleHBvc3VyZSBjYW4gY29tZSBmcm9tIHJvYWQgdmVoaWNsZXMuCgpXZSB1c2UgT3BlbiBTdHJlZXQgTWFwIChPU00pIGRhdGEgdG8gZ2V0IHRoZSBtYWluIHJvYWRzICh0aGVyZSBhcmUgZmV3IG9mIHRoZXNlIGluIEJsYW50eXJlLi4uIGJ1dCBzZWUgdGhlIG1vc3QgdHJhZmZpYykuIExhdGVyIGNvdWxkIGNvbnNpZGVyIGluY2x1ZGluZyBzb21lIHNtYWxsZXIgcm9hZC4uLgoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KCiNnZXQgdGhlIE9TTSBmZWF0dXJlcy4KcSA8LSBvcHEoYmJveCA9IGJib3hfYnVmZmVyZWQpICU+JQogIGFkZF9vc21fZmVhdHVyZShrZXkgPSAnaGlnaHdheScsIAogICAgICAgICAgICAgICAgICB2YWx1ZSA9IGMoJ3ByaW1hcnknLCAnc2Vjb25kYXJ5JywgJ3RlcnRpYXJ5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndHJ1bmsnLCAnbW90b3J3YXknKSkKCiNpbXBvcnQKb3NtX3JvYWRzIDwtIG9zbWRhdGFfc2YocSkKCiMjZ2V0IHJlYWR5LgptYWluX3JvYWRzIDwtIG9zbV9yb2FkcyRvc21fbGluZXMKbWFpbl9yb2FkcyA8LSBzdF90cmFuc2Zvcm0obWFpbl9yb2Fkcywgc3RfY3JzKG13XzEwMG0pKQoKI3Bsb3Qgcm9hZHMKbWFpbl9yb2FkcyAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihkYXRhID0gc2NhbGVfNzJfY2x1c3RlcnMsIGNvbG91cj0iZGFya3JlZCIpICsKICBnZW9tX3NmKCkgCgojY3JvcCB0byBncmlkCm1haW5fcm9hZHNfY3JvcHBlZCA8LSBzdF9jcm9wKG1haW5fcm9hZHMsIGJib3hfYnVmZmVyZWQpCgojcGxvdCBhZ2Fpbi4KbWFpbl9yb2Fkc19jcm9wcGVkICU+JQogIGdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBzY2FsZV83Ml9jbHVzdGVycywgY29sb3VyPSJkYXJrcmVkIikgKwogIGdlb21fc2YoKSAKCiNnZXQgY2VudHJvaWRzIG9mIGdyaWQgY2VsbHMKZ3JpZF9jZW50cm9pZHMgPC0gc3RfY2VudHJvaWQobXdfMTAwbV9ncmlkX3NmKQoKI3VzZSBuZWFyZXN0IG5laWdoYm91ciBzZWFyY2ggdG8gZ2V0IHRoZSBkaXN0YW5jZSBmcm9tIHRoZSBncmlkIGNlbGwgY2VudHJvaWQgdG8gdGhlIG5lYXJlc3QgbWFpbiByb2FkLgpuZWFyZXN0X3JvYWRzIDwtIHN0X25uKGdyaWRfY2VudHJvaWRzLCBtYWluX3JvYWRzX2Nyb3BwZWQsIGsgPSAxLCByZXR1cm5EaXN0ID0gVFJVRSkKZGlzdF90b19yb2FkX20gPC0gc2FwcGx5KG5lYXJlc3Rfcm9hZHMkZGlzdCwgYFtgLCAxKQoKI3NhbWUgYXMgYmVmb3JlOiBhZGQgdG8gZ3JpZAptd18xMDBtX2dyaWRfc2YkZGlzdF90b19yb2FkX20gPC0gZGlzdF90b19yb2FkX20KCiNjaGVjayBwbG90Cm13XzEwMG1fZ3JpZF9zZiAlPiUKICBtdXRhdGUoeCA9IHN0X2Nvb3JkaW5hdGVzKHN0X2NlbnRyb2lkKC4pKVssIDFdLAogICAgICAgICB5ID0gc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoLikpWywgMl0pICU+JQogIGdncGxvdCgpICsKICBnZW9tX3RpbGUoYWVzKHg9eCwgeT15LCBmaWxsPWRpc3RfdG9fcm9hZF9tKSkgKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJHIiwgZGlyZWN0aW9uID0gLTEpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJncmV5NzgiKSkgKwogIHRoZW1lX2dnZGlzdCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJncmV5NzgiKSkKCgoKYGBgCgoKSm9pbiBhbGwgdG9nZXRoZXIgaW50byB0aGUgbW9kZWxsaW5nIGRhdGFzZXQsIGFuZCBqdXN0IGxhc3QgdGlkeS11cC4KCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CgphcV9tb2RlbF9kYXRhIDwtIHN0X2FzX3NmKGFxX21vZGVsX2RhdGEsIGNvb3JkcyA9IGMoIngiLCAieSIpLCBjcnMgPSBzdF9jcnMobXdfMTAwbSkpCgphcV9tb2RlbF9kYXRhIDwtIHN0X2pvaW4oYXFfbW9kZWxfZGF0YSwgbXdfMTAwbV9ncmlkX3NmKQoKYXFfbW9kZWxfZGF0YSA8LSBhcV9tb2RlbF9kYXRhICU+JQogIG11dGF0ZSh4ID0gc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoLikpWywgMV0sCiAgICAgICAgIHkgPSBzdF9jb29yZGluYXRlcyhzdF9jZW50cm9pZCguKSlbLCAyXSkgJT4lCiAgc3RfZHJvcF9nZW9tZXRyeSgpICU+JQogIG11dGF0ZShidWlsZGluZ19jb3ZlcmFnZV9wY3QgPSBidWlsZGluZ19jb3ZlcmFnZV9wY3QvMTAwKQoKYGBgCgoKIyMjIE1vZGVsIDE6CgoKIldlIGZpdHRlZCBhIHNwYXRpYWxseSBzbW9vdGggcmVncmVzc2lvbiBtb2RlbCBmb3IgbG9nLXRyYW5zZm9ybWVkIFBNMi41IGNvbmNlbnRyYXRpb25zIHVzaW5nIGEgR2F1c3NpYW4gcHJvY2VzcyAoR1ApIHNtb290aCBvdmVyIHNwYXRpYWwgY29vcmRpbmF0ZXMgKHgsIHkpIHRvIGNhcHR1cmUgZmxleGlibGUgc3BhdGlhbCB0cmVuZHMuIFNlYXNvbmFsIHZhcmlhdGlvbiB3YXMgbW9kZWxsZWQgdXNpbmcgYSBGb3VyaWVyIHNlcmllcyBleHBhbnNpb24gb2YgZGF5LW9mLXllYXIgdXAgdG8gdGhlIDNyZCBoYXJtb25pYyAoaS5lLiwgc2luZSBhbmQgY29zaW5lIHRlcm1zIGZvciBhbm51YWwsIHNlbWktYW5udWFsLCBhbmQgdHJpLWFubnVhbCBjeWNsZXMpIHRvIGFjY291bnQgZm9yIGNvbXBsZXggc2Vhc29uYWwgcGF0dGVybnMuIFRoZSBtb2RlbCB3YXMgZml0dGVkIGluIGEgQmF5ZXNpYW4gZnJhbWV3b3JrIHVzaW5nIGJybXMgd2l0aCBhIEdhdXNzaWFuIGxpa2VsaWhvb2QgYW5kIHRoZSBjbWRzdGFuciBiYWNrZW5kLiIKCk5vdGUsIHByaW9ycyBhcmUgc3RpbGwgY2F1c2luZyBpc3N1ZXMgZm9yIG1lLCBzbyB3ZSB3aWxsIGNvbW1lbnQgb3V0IG5vdywgYW5kIHVzZSB0aGUgZGVmYXVseSBzdGFuIHdlYWtseSBpbmZvcm1hdGl2ZSBwcmlvcnMKClByaW9ycwoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KIyAKIyBwcmlvcnMgPC0gYygKIyAgIHByaW9yKG5vcm1hbCgwLCAxKSwgY2xhc3MgPSAiSW50ZXJjZXB0IiksCiMgICBwcmlvcihub3JtYWwoMCwxKSwgY2xhc3MgPSAiYiIpLAojICAgcHJpb3Ioc3R1ZGVudF90KDMsIDAsIDIuNSksIGNsYXNzID0gInNpZ21hIiksCiMgICBwcmlvcihleHBvbmVudGlhbCgwLjUpLCBjbGFzcyA9ICJzZGdwIikKIyApCgpgYGAKCkZpdCBwcmlvciBvbmx5IG1vZGVsCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyfQojIAojIG0xX3ByaW9yIDwtIGJybSgKIyAgICAgZm9ybXVsYSA9IGxvZ19wbTJfNSB+IGdwKHgsIHksIGs9MTUpICsKIyAgICAgICBzaW5fZG95MSArIGNvc19kb3kxICsKIyAgICAgICBzaW5fZG95MiArIGNvc19kb3kyICsKIyAgICAgICBzaW5fZG95MyArIGNvc19kb3kzLAojICAgICBkYXRhID0gYXFfbW9kZWxfZGF0YSwKIyAgICAgZmFtaWx5ID0gZ2F1c3NpYW4oKSwKIyAgICAgcHJpb3IgPSBwcmlvcnMsCiMgICAgIHNhbXBsZV9wcmlvciA9ICJvbmx5IiwKIyAgICAgY2hhaW5zID0gNCwgY29yZXMgPSA0LAojICAgICBiYWNrZW5kID0gImNtZHN0YW5yIgojICAgKQojIAojIAojIHN1bW1hcnkobTFfcHJpb3IpCiMgcGxvdChtMV9wcmlvcikKCmBgYAoKTm93IG1vZGVsIHdpdGggZGF0YS4KCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyfQptMSA8LSBicm0oCiAgICBmb3JtdWxhID0gbG9nX3BtMl81IH4gZ3AoeCwgeSwgaz0xNSkgICsKICAgIHNpbl9kb3kxICsgY29zX2RveTEgKwogICAgc2luX2RveTIgKyBjb3NfZG95MiArCiAgICBzaW5fZG95MyArIGNvc19kb3kzLAogICAgZGF0YSA9IGFxX21vZGVsX2RhdGEsCiAgICBmYW1pbHkgPSBnYXVzc2lhbigpLAogICAgI3ByaW9yID0gcHJpb3JzLAogICAgY2hhaW5zID0gNCwgY29yZXMgPSA0LAogICAgYmFja2VuZCA9ICJjbWRzdGFuciIKICApCgpzdW1tYXJ5KG0xKQpjb25kaXRpb25hbF9lZmZlY3RzKG0xKQpwcF9jaGVjayhtMSkKcGxvdChtMSkKCmBgYAoKQ29tcGFyZSBwcmlvci1vbmx5IG1vZGVsIHRvIG1vZGVsIHdpdGggZGF0YSB1c2luZyBgcHJpb3JzZW5zZWAgcGFja2FnZToKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CgojIG0xX2RyYXdzIDwtIGFzX2RyYXdzX2RmKG0xKQojIAojICMgRXh0cmFjdCBwcmlvciBhbmQgcG9zdGVyaW9yIGRyYXdzCiMgcG93ZXJzY2FsZV9zZW5zaXRpdml0eShtMSwgdmFyaWFibGUgPSBjKCJiX0ludGVyY2VwdCIsICJiX3Npbl9kb3kiLCAiYl9jb3NfZG95IiwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZGdwX2dweHkiLCAic2lnbWEiLCAiSW50ZXJjZXB0IikpCiMgCiMgcG93ZXJzY2FsZV9wbG90X2RlbnMobTEsIHZhcmlhYmxlID0gYygiYl9JbnRlcmNlcHQiLCAiYl9zaW5fZG95IiwgImJfY29zX2RveSIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2RncF9ncHh5IiwgInNpZ21hIiwgIkludGVyY2VwdCIpKQpgYGAKClByZWRpY3Rpb25zIGJ5IHNwYWNlIGFuZCB0aW1lLiBIZXJlLCBhbHRob3VnaCB3ZSBvbmx5IGhhdmUgZGF0YSB3aXRoaW4gY2x1c3RlcnMsIHdlIHdpbGwgcHJlZGljdCBmb3IgY2VsbHMgb3V0c2lkZSBvZiBjbHVzdGVycyBiYXNlZCBvbiBjb3ZhcmlhdGVzLgpXZSB3aWxsIGFsc28gcHJlZGljdCBmb3IgdGhlIG1vbnRoIGZvciB3aGNpaCB3ZSBkbyBub3QgaGF2ZSBkYXRhLgoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KCiNzZXRfdXAgcHJlZGljdGlvbiBkYXRlIGZyYW1lCm5kX20xIDwtIHN0X2FzX3NmKG13XzEwMG1fY3JvcHBlZCkgICU+JQogIG11dGF0ZShjZW50cm9pZCA9IHN0X2NlbnRyb2lkKGdlb21ldHJ5KSkgJT4lCiAgbXV0YXRlKHggPSBzdF9jb29yZGluYXRlcyhjZW50cm9pZClbLCAxXSwKICAgICAgICAgeSA9IHN0X2Nvb3JkaW5hdGVzKGNlbnRyb2lkKVssIDJdKSAlPiUKICBzZWxlY3QoLWNlbnRyb2lkKSAgJT4lCiAgc3RfZHJvcF9nZW9tZXRyeSgpICU+JQogIHJlbmFtZShwb3BfZGVuc2l0eSA9IDEpICU+JQogIG11dGF0ZShwb3BfZGVuc2l0eV9rbTIgPSBwb3BfZGVuc2l0eSAvIDAuMDEpCgojZ2V0IHRoZSBmaXJzdCBkYXkgb2YgZWFjaCBtb250aCBmb3IgcHJlZGljdGlvbgpmaXJzdF9kYXlzIDwtIHltZChwYXN0ZTAoIjIwMjAtIiwgc3ByaW50ZigiJTAyZCIsIDE6MTIpLCAiLTAxIikpCmZpcnN0X2RheV9kb3kgPC0geWRheShmaXJzdF9kYXlzKQoKI2NhbGN1bGF0ZSBGb3VyaWVyIHRlcm1zCmZpcnN0X2RheV9zZWFzb25hbGl0eSA8LSB0aWJibGUoCiAgbWVhbl9kb3kgPSBmaXJzdF9kYXlfZG95LAogIHNpbl9kb3kxID0gc2luKDIgKiBwaSAqIG1lYW5fZG95IC8gMzY1LjI1KSwKICBjb3NfZG95MSA9IGNvcygyICogcGkgKiBtZWFuX2RveSAvIDM2NS4yNSksCiAgc2luX2RveTIgPSBzaW4oNCAqIHBpICogbWVhbl9kb3kgLyAzNjUuMjUpLAogIGNvc19kb3kyID0gY29zKDQgKiBwaSAqIG1lYW5fZG95IC8gMzY1LjI1KSwKICBzaW5fZG95MyA9IHNpbig2ICogcGkgKiBtZWFuX2RveSAvIDM2NS4yNSksCiAgY29zX2RveTMgPSBjb3MoNiAqIHBpICogbWVhbl9kb3kgLyAzNjUuMjUpLAogIGRhdGUgPSBmaXJzdF9kYXlzCikKCiNleHBhbmQgZ3JpZCBmb3IgcHJlZGljdGlvbgpuZF9tMSA8LSBuZF9tMSAlPiUKICBjcm9zc2luZyhmaXJzdF9kYXlfc2Vhc29uYWxpdHkpCgojdGFrZSBwb3N0ZXJpb3IgZHJhd3MgLSBub3RlIHN0b3JpbmcgYXMgYW4gcnZhcnMgb2JqZWN0IGZvciBlZmZpY2llbmN5CiNub3RlIGNhbiBvbmx5IG1hbmFnZSB0aGlzIHdpdGhvdXQgY3Jhc2hpbmcgY29tcHV0ZXIhCiN0byBhZGRyZXNzIGxhdGVyLCBhbmQgaW1wcm92ZSBlZmZpY2llbnkgZm9yIG1vcmUgZHJhd3MKbTFfZHJhd3MgPC0gYWRkX2VwcmVkX3J2YXJzKG9iamVjdCA9IG0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3ZGF0YSA9IG5kX20xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmRyYXdzID0gMjAwKSAKCiNub3cgZXh0cmFjdCB0aGUgc3VtbWFyeSBtZWFuIGFuZCBzZCBmb3IgZWFjaCBtb250aC1ncmlkIGNlbGwgY29tYmluYXRpb24KbTFfZXByZWRfYXJyYXkgPC0gcG9zdGVyaW9yOjpkcmF3c19vZihtMV9kcmF3cyQuZXByZWQpCgojY29tcHV0ZSBwb3N0ZXJpb3IgbWVhbnMgcGVyIGxvY2F0aW9uCm0xX2RyYXdzJC5lcHJlZF9tZWFuIDwtIGNvbE1lYW5zKG0xX2VwcmVkX2FycmF5KQoKI2NvbXB1dGUgcG9zdGVyaW9yIHNkcyBwZXIgbG9jYXRpb24KbTFfZHJhd3MkLmVwcmVkX3NkIDwtIGFwcGx5KG0xX2VwcmVkX2FycmF5LCAyLCBzZCkKCm0xX3N1bSA8LSBtMV9kcmF3cyAlPiUgCiAgc2VsZWN0KGdyaWRfaWQsIHgsIHksIGRhdGUsIG1vbnRoLCAuZXByZWRfbWVhbiwgLmVwcmVkX3NkKQoKCiNwbG90IHByZWRpY3Rpb25zCm0xX3N1bSAlPiUgIAogIG11dGF0ZShkYXRlID0gbW9udGgoZGF0ZSwgbGFiZWw9VFJVRSkpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3RpbGUoYWVzKHggPSB4LCB5PXksIGZpbGw9LmVwcmVkX2xvZ19wbTIuNSkpICsKICBnZW9tX3NmKGRhdGEgPSBzY2FsZV83Ml9jbHVzdGVycywgY29sb3VyPSJncmV5NzgiLCBmaWxsPU5BKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArCiAgZmFjZXRfd3JhcChkYXRlfi4pICsKICBsYWJzKHRpdGxlID0gIkxvZyhQTTIuNSkgZXhwb3N1cmUiLAogICAgICAgeD0iIiwKICAgICAgIHk9IiIpICsKICB0aGVtZV9nZ2Rpc3QoKSArCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPU5BLCBjb2xvdXI9ImdyZXk3OCIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0PTEpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImdyZXk3OCIpKQoKYGBgCgpOb3cganVzdCBkcmF3IDUwIHJhbmRvbSBjb29yZGluYXRlcywgYW5kIHByZWRpY3QgYnkgdGltZSB0byBzZWUgd2hldGhlciB3ZSBjYXB0dXJlZCB0aGUgdHJlbmQuCgpgYGB7ciwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEyfQojc2FtcGxlIGNvb3JkaW5hdGUgcG9pbnRzIGZyb20gdGhlIGhvdXNlaG9sZCBkYXRhc2V0CiN3ZSB3aWxsIGZpeCB0aGUgc21hbGwgbnVtYmVyIHNhbXBsZWQgbGF0ZXIhCnNldC5zZWVkKDEyMykgCnNhbXBsZWRfcG9pbnRzX20xIDwtIGFxX21vZGVsX2RhdGEgJT4lCiAgc2FtcGxlX24oNTApICU+JQogIHNlbGVjdCh4LCB5KQoKI2dlbmVyYXRlIERPWSAw4oCTMzY1IGFuZCBjYWxjdWxhdGUgRm91cmllciB0ZXJtcwpkb3lfZ3JpZCA8LSB0aWJibGUoZG95ID0gMDozNjUpICU+JQogIG11dGF0ZSgKICAgIHNpbl9kb3kxID0gc2luKDIgKiBwaSAqIGRveSAvIDM2NSksCiAgICBjb3NfZG95MSA9IGNvcygyICogcGkgKiBkb3kgLyAzNjUpLAogICAgc2luX2RveTIgPSBzaW4oNCAqIHBpICogZG95IC8gMzY1KSwKICAgIGNvc19kb3kyID0gY29zKDQgKiBwaSAqIGRveSAvIDM2NSksCiAgICBzaW5fZG95MyA9IHNpbig2ICogcGkgKiBkb3kgLyAzNjUpLAogICAgY29zX2RveTMgPSBjb3MoNiAqIHBpICogZG95IC8gMzY1KQogICkKCiNleHBhbmQgZ3JpZCBhY3Jvc3Mgc2FtcGxlZCBsb2NhdGlvbnMKcHJlZGljdGlvbl9kZl9tMSA8LSBzYW1wbGVkX3BvaW50c19tMSAlPiUKICBjcm9zc2luZyhkb3lfZ3JpZCkKCiNhZGQgcHJlZGljdGlvbnMKcHJlZHNfbTEgPC0gYWRkX2VwcmVkX2RyYXdzKG9iamVjdCA9IG0xLCBuZXdkYXRhID0gcHJlZGljdGlvbl9kZl9tMSkKCiNzdW1tYXJpc2UKcHJlZHNfbTFfc3VtIDwtIHByZWRzX20xICU+JQogIHVuZ3JvdXAoKSAlPiUKICBncm91cF9ieShkb3kpICU+JQogIHN1bW1hcmlzZSguZXByZWRfbWVhbiA9IG1lYW4oLmVwcmVkKSwKICAgICAgICAgICAgLmxvd2VyID0gcXVhbnRpbGUoLmVwcmVkLCBwcm9icz0wLjAyNSksCiAgICAgICAgICAgIC51cHBlciA9IHF1YW50aWxlKC5lcHJlZCwgcHJvYnMgPSAwLjk3NSkpCgojR0V0IHRoZSBvYnNlcnZlZCBkYXRhCm9ic2VydmVkX2RhdGEgPC0gYXFfbW9kZWxfZGF0YSAlPiUKICBzZWxlY3QobWVhbl9kb3ksIGxvZ19wbTJfNSkgCgojcGxvdApwcmVkc19tMV9zdW0gJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fcmliYm9uKGFlcyh4PWRveSwgeW1pbj0ubG93ZXIsIHltYXggPSAudXBwZXIpLCBmaWxsPSJzdGVlbGJsdWUiLCBhbHBoYT0wLjMpICsKICBnZW9tX2xpbmUoYWVzKHg9ZG95LCB5PS5lcHJlZF9tZWFuKSkgKwogIGdlb21faml0dGVyKGRhdGEgPSBvYnNlcnZlZF9kYXRhLCBhZXMoeCA9IG1lYW5fZG95LCB5ID0gbG9nX3BtMl81KSwKICAgICAgICAgICAgICBjb2xvciA9ICJkYXJrcmVkIiwgYWxwaGEgPSAwLjYsIHdpZHRoID0gMC41LCBoZWlnaHQgPSAwLjAsIHNpemUgPSAxLjIpICsKICBsYWJzKHRpdGxlID0gIk1vZGVsLWVzdGltYXRlZCBsb2coUE0yLjUpIHdpdGggZW1waXJpY2FsIG1lYXN1cmVtZW50cyIsCiAgICAgICBzdWJ0aXRsZSA9ICJNb2RlbCBwcmVkaWN0aW9ucyB3aXRoIDk1JSBDckkgYW5kIG9ic2VydmVkIGRhdGEgcG9pbnRzIiwKICAgICAgIHggPSAiRGF5IG9mIHllYXIiLAogICAgICAgeSA9ICJsb2coUE0yLjUpIiwKICAgICAgIGNhcHRpb24gPSAiTW9kZWxsZWQgZXN0aW1hdGVzIHJlc3RyaWN0ZWQgdG8gd2l0aGluIGNsdXN0ZXJzIikgKwogIHRoZW1lX2dnZGlzdCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJncmV5NzgiKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpgYGAKCiMjIyBNb2RlbCAyOiBXaXRoIGNvdmFyaWF0ZXMKCk5vdyB3ZSBpbmNsdWRlIGdyaWQgbGV2ZWwgY292YXJpYXRlcyBvZiBkaXN0YW5jZSB0byB0aGUgcm9hZCwgcG9wdWxhdGlvbiBkZW5zaXR5LCBhbmQgYnVpbGRpbmcgZm9vdHByaW50IHBlcmNlbnQsIGFsb25nIHdpdGh0IHRoZSBtZWFuIHRlbXAgYW5kIGh1aWRpdHkgb24gdGhlIGRheSBvZiBtZWFzdXJlbWVudCAoZnJvbSB0aGUgcHVycGxlIGFpciBtb25pdG9ycykKCkFnYWluLCBwcmlvcnMgdG8gYmUgZml4ZWQgbGF0ZXIKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CiMgcHJpb3JzIDwtIGMoCiMgICBwcmlvcihub3JtYWwoMCwgMSksIGNsYXNzID0gIkludGVyY2VwdCIpLAojICAgcHJpb3Iobm9ybWFsKDAsMSksIGNsYXNzID0gImIiKSwKIyAgIHByaW9yKHN0dWRlbnRfdCgzLCAwLCAyLjUpLCBjbGFzcyA9ICJzaWdtYSIpLAojICAgcHJpb3IoZXhwb25lbnRpYWwoMC41KSwgY2xhc3MgPSAic2RncCIpLAojICkKCgptMiA8LSBicm0oCiAgICBmb3JtdWxhID0gbG9nX3BtMl81IH4gZ3AoeCwgeSwgaz0xNSkgICsKICAgICAgcyhtZWFuX3RlbXBfYywgaz01KSArIAogICAgICBzKG1lYW5fY3VycmVudF9odW1pZGl0eSwgaz01KSArCiAgICAgIHMocG9wX2RlbnNpdHlfa20yLCBrPTUpICsKICAgICAgcyhidWlsZGluZ19jb3ZlcmFnZV9wY3QsIGs9NSkgKwogICAgICBzKGRpc3RfdG9fcm9hZF9tLCBrPTUpICsKICAgICAgc2luX2RveTEgKyBjb3NfZG95MSArCiAgICAgIHNpbl9kb3kyICsgY29zX2RveTIgKwogICAgICBzaW5fZG95MyArIGNvc19kb3kzLAogICAgZGF0YSA9IGFxX21vZGVsX2RhdGEsCiAgICBmYW1pbHkgPSBnYXVzc2lhbigpLAogICAgI3ByaW9yID0gcHJpb3JzLAogICAgY2hhaW5zID0gNCwgY29yZXMgPSA0LAogICAgYmFja2VuZCA9ICJjbWRzdGFuciIKICApCgpzdW1tYXJ5KG0yKQpjb25kaXRpb25hbF9lZmZlY3RzKG0yKQpwcF9jaGVjayhtMikKcGxvdChtMikKCgpgYGAKUHJlZGljdGlvbnMgYnkgc3BhY2UgYW5kIHRpbWUKCmBgYHtyLCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9MTJ9CgojZmlyc3Qgd2UgbmVlZCBhIHByZWRpY3Rpb24gZGF0YWZyYW1lIHdpdGggYWxsIG9mIHRoZSBjb3ZhcmlhdGUgZGF0YQoKI2V4dHJhY3QgbW9udGggZnJvbSBkYXRlIHZhcmlhYmxlCmFxX21vZGVsX2RhdGEgPC0gYXFfbW9kZWxfZGF0YSAgJT4lCiAgbXV0YXRlKG1vbnRoID0gbHVicmlkYXRlOjptb250aChhcy5EYXRlKG1lYW5fZG95LCBvcmlnaW4gPSAiMjAxOS0xMi0zMSIpKSkKCiNjYWxjdWxhdGUgbW9udGhseSBtZWFucwptb250aGx5X21lYW5zIDwtIGFxX21vZGVsX2RhdGEgJT4lCiAgZ3JvdXBfYnkobW9udGgpICU+JQogIHN1bW1hcmlzZSgKICAgIG1lYW5fdGVtcF9jID0gbWVhbihtZWFuX3RlbXBfYywgbmEucm0gPSBUUlVFKSwKICAgIG1lYW5fY3VycmVudF9odW1pZGl0eSA9IG1lYW4obWVhbl9jdXJyZW50X2h1bWlkaXR5LCBuYS5ybSA9IFRSVUUpCiAgKQoKI05vIGRhdGEgY29sbGVjdGlvbiBpbiBBcHJpbCAtIGhlcmUgd2Ugd2lsbCBqdXN0IGludGVycG9sYXRlCiNjYW4gZG8gYmV0dGVyIGxhdGVyLi4uCm1hcmNoX3RlbXAgPC0gbW9udGhseV9tZWFucyAlPiUgZmlsdGVyKG1vbnRoID09IDMpICU+JSBwdWxsKG1lYW5fdGVtcF9jKQptYXlfdGVtcCA8LSBtb250aGx5X21lYW5zICU+JSBmaWx0ZXIobW9udGggPT0gNSkgJT4lIHB1bGwobWVhbl90ZW1wX2MpCmFwcmlsX3RlbXAgPC0gKG1hcmNoX3RlbXAgKyBtYXlfdGVtcCkgLyAyCgptYXJjaF9odW1pZGl0eSA8LSBtb250aGx5X21lYW5zICU+JSBmaWx0ZXIobW9udGggPT0gMykgJT4lIHB1bGwobWVhbl9jdXJyZW50X2h1bWlkaXR5KQptYXlfaHVtaWRpdHkgPC0gbW9udGhseV9tZWFucyAlPiUgZmlsdGVyKG1vbnRoID09IDUpICU+JSBwdWxsKG1lYW5fY3VycmVudF9odW1pZGl0eSkKYXByaWxfaHVtaWRpdHkgPC0gKG1hcmNoX2h1bWlkaXR5ICsgbWF5X2h1bWlkaXR5KSAvIDIKCiNhZGQgdGhlc2UgaW50byB0aGUgcHJlZGljdGlvbiBkYXRhZnJhbWUKbW9udGhseV9tZWFucyA8LSBtb250aGx5X21lYW5zICU+JQogIGFkZF9yb3cobW9udGg9NCwgCiAgICAgICAgICBtZWFuX3RlbXBfYyA9IGFwcmlsX3RlbXAsCiAgICAgICAgICBtZWFuX2N1cnJlbnRfaHVtaWRpdHkgPSBhcHJpbF9odW1pZGl0eSkgJT4lCiAgYXJyYW5nZShtb250aCkKCiNzZXRfdXAgcHJlZGljdGlvbiBkYXRlIGZyYW1lCm5kX20yIDwtIG13XzEwMG1fZ3JpZF9zZiAlPiUKICBtdXRhdGUoeCA9IHN0X2Nvb3JkaW5hdGVzKHN0X2NlbnRyb2lkKC4pKVssIDFdLAogICAgICAgICB5ID0gc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoLikpWywgMl0pICU+JQogIHN0X2Ryb3BfZ2VvbWV0cnkoKSAlPiUKICByZW5hbWUocG9wX2RlbnNpdHkgPSAxKSAlPiUKICBtdXRhdGUocG9wX2RlbnNpdHlfa20yID0gcG9wX2RlbnNpdHkgLyAwLjAxKQoKI2dldCB0aGUgZmlyc3QgZGF5IG9mIGVhY2ggbW9udGggZm9yIHByZWRpY3Rpb24KZmlyc3RfZGF5cyA8LSB5bWQocGFzdGUwKCIyMDIwLSIsIHNwcmludGYoIiUwMmQiLCAxOjEyKSwgIi0wMSIpKQpmaXJzdF9kYXlfZG95IDwtIHlkYXkoZmlyc3RfZGF5cykKCiNjYWxjdWxhdGUgRm91cmllciB0ZXJtcwpmaXJzdF9kYXlfc2Vhc29uYWxpdHkgPC0gdGliYmxlKAogIG1lYW5fZG95ID0gZmlyc3RfZGF5X2RveSwKICBzaW5fZG95MSA9IHNpbigyICogcGkgKiBtZWFuX2RveSAvIDM2NS4yNSksCiAgY29zX2RveTEgPSBjb3MoMiAqIHBpICogbWVhbl9kb3kgLyAzNjUuMjUpLAogIHNpbl9kb3kyID0gc2luKDQgKiBwaSAqIG1lYW5fZG95IC8gMzY1LjI1KSwKICBjb3NfZG95MiA9IGNvcyg0ICogcGkgKiBtZWFuX2RveSAvIDM2NS4yNSksCiAgc2luX2RveTMgPSBzaW4oNiAqIHBpICogbWVhbl9kb3kgLyAzNjUuMjUpLAogIGNvc19kb3kzID0gY29zKDYgKiBwaSAqIG1lYW5fZG95IC8gMzY1LjI1KSwKICBkYXRlID0gZmlyc3RfZGF5cwopICU+JQogIG11dGF0ZShtb250aCA9IGx1YnJpZGF0ZTo6bW9udGgoYXMuRGF0ZShtZWFuX2RveSwgb3JpZ2luID0gIjIwMTktMTItMzEiKSkpICU+JQogIGxlZnRfam9pbihtb250aGx5X21lYW5zKQoKbmRfbTIgPC0gbmRfbTIgJT4lCiAgY3Jvc3NpbmcoZmlyc3RfZGF5X3NlYXNvbmFsaXR5KQoKI3Rha2UgcG9zdGVyaW9yIGRyYXdzIC0gbm90ZSBzdG9yaW5nIGFzIGFuIHJ2YXJzIG9iamVjdCBmb3IgZWZmaWNpZW5jeQptMl9kcmF3cyA8LSBhZGRfZXByZWRfcnZhcnMob2JqZWN0ID0gbTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdkYXRhID0gbmRfbTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZHJhd3MgPSAyMDApICNub3RlIGNhbiBvbmx5IG1hbmFnZSB0aGlzIHdpdGhvdXQgY3Jhc2hpbmcgY29tcHV0ZXIhCgojbm93IGV4dHJhY3QgdGhlIHN1bW1hcnkgbWVhbiBhbmQgc2QgZm9yIGVhY2ggbW9udGgtZ3JpZCBjZWxsIGNvbWJpbmF0aW9uCm0yX2VwcmVkX2FycmF5IDwtIHBvc3Rlcmlvcjo6ZHJhd3Nfb2YobTJfZHJhd3MkLmVwcmVkKQoKI2NvbXB1dGUgcG9zdGVyaW9yIG1lYW5zIHBlciBsb2NhdGlvbgptMl9kcmF3cyQuZXByZWRfbWVhbiA8LSBjb2xNZWFucyhtMl9lcHJlZF9hcnJheSkKCiNjb21wdXRlIHBvc3RlcmlvciBzZCBwZXIgbG9jYXRpb24KbTJfZHJhd3MkLmVwcmVkX3NkIDwtIGFwcGx5KGVwcmVkX2FycmF5LCAyLCBzZCkKCm0yX3N1bSA8LSBtMl9kcmF3cyAlPiUgCiAgc2VsZWN0KGdyaWRfaWQsIHgsIHksIGRhdGUsIG1vbnRoLCAuZXByZWRfbWVhbiwgLmVwcmVkX3NkKQoKCiNwbG90IHByZWRpY3Rpb25zCm0yX3N1bSAlPiUgIAogIG11dGF0ZShkYXRlID0gbW9udGgoZGF0ZSwgbGFiZWwgPSBUUlVFKSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fdGlsZShhZXMoeCA9IHgsIHk9eSwgZmlsbD0uZXByZWRfbWVhbikpICsKICBnZW9tX3NmKGRhdGEgPSBzY2FsZV83Ml9jbHVzdGVycywgY29sb3VyPSJncmV5NzgiLCBmaWxsPU5BKSArCiAgI2dlb21fc2YoZGF0YSA9IG1haW5fcm9hZHNfY3JvcHBlZCwgY29sb3VyPSJ3aGl0ZSIpICsgI3JvYWRzIGxvb2tpbmcgYSBiaXQgbWVzc3kgd2hlbiBwbG90dGVkIC0gd29yayBvbiB0aGlzLgogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKwogIGZhY2V0X3dyYXAoZGF0ZX4uKSArCiAgbGFicyh0aXRsZSA9ICJMb2coUE0yLjUpIGV4cG9zdXJlIiwKICAgICAgIHg9IiIsCiAgICAgICB5PSIiLAogICAgICAgY2FwdGlvbiA9ICJXaGl0ZSBib3VuZGFyaWVzIGFyZSBTQ0FMRSBzdHVkeSBjbHVzdGVycyIpICsKICB0aGVtZV9nZ2Rpc3QoKSArCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPU5BLCBjb2xvdXI9ImdyZXk3OCIpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImdyZXk3OCIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTQ1LCBoanVzdD0xKSkKCiNwbG90IHNkCm0yX3N1bSAlPiUgIAogIG11dGF0ZShkYXRlID0gbW9udGgoZGF0ZSwgbGFiZWwgPSBUUlVFKSkgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fdGlsZShhZXMoeCA9IHgsIHk9eSwgZmlsbD0uZXByZWRfc2QpKSArCiAgZ2VvbV9zZihkYXRhID0gc2NhbGVfNzJfY2x1c3RlcnMsIGNvbG91cj0iZ3JleTc4IiwgZmlsbD1OQSkgKwogICNnZW9tX3NmKGRhdGEgPSBtYWluX3JvYWRzX2Nyb3BwZWQsIGNvbG91cj0id2hpdGUiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gIkYiKSArCiAgZmFjZXRfd3JhcChkYXRlfi4pICsKICBsYWJzKHRpdGxlID0gIkxvZyhQTTIuNSkgZXhwb3N1cmUiLAogICAgICAgeD0iIiwKICAgICAgIHk9IiIsCiAgICAgICBjYXB0aW9uID0gIldoaXRlIGJvdW5kYXJpZXMgYXJlIFNDQUxFIHN0dWR5IGNsdXN0ZXJzIikgKwogIHRoZW1lX2dnZGlzdCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9TkEsIGNvbG91cj0iZ3JleTc4IiksCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiZ3JleTc4IiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9NDUsIGhqdXN0PTEpKQoKYGBgCgpTYW1wbGUgY29vcmRpbmF0ZXMsIGFuZCBwbG90IG92ZXIgdGltZQoKYGBge3IsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD0xMn0KCiNzYW1wbGUgY29vcmRpbmF0ZSBwb2ludHMKI3dpbGwgc29ydCBvdXQgdGhlIHNtYWxsIG51bWJlciBsYXRlcgpzZXQuc2VlZCgxMjMpCnNhbXBsZWRfcG9pbnRzX20yIDwtIGFxX21vZGVsX2RhdGEgJT4lCiAgc2FtcGxlX24oNTApICU+JQogIHNlbGVjdCh4LCB5LCBtZWFuX3RlbXBfYywgbWVhbl9jdXJyZW50X2h1bWlkaXR5LCBwb3BfZGVuc2l0eV9rbTIsIGJ1aWxkaW5nX2NvdmVyYWdlX3BjdCwgZGlzdF90b19yb2FkX20sIGdyaWRfaWQsIGxvZ19wbTJfNSkKCiNnZW5lcmF0ZSBET1kgMOKAkzM2NSBhbmQgY2FsY3VsYXRlIEZvdXJpZXIgdGVybXMKZG95X2dyaWQgPC0gdGliYmxlKGRveSA9IHNlcSgwLDM2NSwgYnk9MSkpICU+JQogIG11dGF0ZSgKICAgIHNpbl9kb3kxID0gc2luKDIgKiBwaSAqIGRveSAvIDM2NSksCiAgICBjb3NfZG95MSA9IGNvcygyICogcGkgKiBkb3kgLyAzNjUpLAogICAgc2luX2RveTIgPSBzaW4oNCAqIHBpICogZG95IC8gMzY1KSwKICAgIGNvc19kb3kyID0gY29zKDQgKiBwaSAqIGRveSAvIDM2NSksCiAgICBzaW5fZG95MyA9IHNpbig2ICogcGkgKiBkb3kgLyAzNjUpLAogICAgY29zX2RveTMgPSBjb3MoNiAqIHBpICogZG95IC8gMzY1KQogICkKCiNleHBhbmQgZ3JpZCBhY3Jvc3Mgc2FtcGxlZCBsb2NhdGlvbnMKcHJlZGljdGlvbl9kZl9tMiA8LSBzYW1wbGVkX3BvaW50c19tMiAlPiUKICBjcm9zc2luZyhkb3lfZ3JpZCkKCiNhZGQgcHJlZGljdGlvbnMKcHJlZHNfbTIgPC0gYWRkX2VwcmVkX2RyYXdzKG9iamVjdCA9IG0yLCBuZXdkYXRhID0gcHJlZGljdGlvbl9kZl9tMiwgbmRyYXdzID0gMTAwKQoKI29ic2VydmVkIGRhdGEgZm9yIHBsb3R0aW5nCm9ic2VydmVkX2RhdGEgPC0gYXFfbW9kZWxfZGF0YSAlPiUKICBzZWxlY3QobWVhbl9kb3ksIGxvZ19wbTJfNSkgJT4lCiAgbXV0YXRlKG1lYW5fZG95ID0gcm91bmQobWVhbl9kb3kpKQoKI3Bsb3QKcHJlZHNfbTIgJT4lCiAgdW5ncm91cCgpICU+JQogIGdncGxvdChhZXMoeD1kb3kpKSArCiAgc3RhdF9saW5lcmliYm9uKGFlcyh5PS5lcHJlZCksIC53aWR0aD0wLjk1KSArIAogIGdlb21faml0dGVyKGRhdGEgPSBvYnNlcnZlZF9kYXRhLCBhZXMoeCA9IG1lYW5fZG95LCB5ID0gbG9nX3BtMl81KSwKICAgICAgICAgICAgICBjb2xvciA9ICJkYXJrcmVkIiwgYWxwaGEgPSAwLjYsIHdpZHRoID0gMC41LCBoZWlnaHQgPSAwLjAsIHNpemUgPSAxLjIpICsKICBzY2FsZV9maWxsX2JyZXdlcigpICsKICBsYWJzKHRpdGxlID0gIk1vZGVsLWVzdGltYXRlZCBsb2coUE0yLjUpIHdpdGggZW1waXJpY2FsIG1lYXN1cmVtZW50cyIsCiAgICAgICBzdWJ0aXRsZSA9ICJNb2RlbCBwcmVkaWN0aW9ucyB3aXRoIDk1JSBDckkgYW5kIG9ic2VydmVkIGRhdGEgcG9pbnRzIiwKICAgICAgIHggPSAiRGF5IG9mIHllYXIiLAogICAgICAgeSA9ICJsb2coUE0yLjUpIiwKICAgICAgIGNhcHRpb24gPSAiTW9kZWxsZWQgZXN0aW1hdGVzIHJlc3RyaWN0ZWQgdG8gd2l0aGluIGNsdXN0ZXJzIikgKwogIHRoZW1lX2dnZGlzdCgpICsKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJncmV5NzgiKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgoKCmBgYAoKCkNvbXBhcmUgbW9kZWxzLCB1c2luZyBMT08gQ1YKCmBgYHtyfQoKbGlicmFyeShsb28pCgpsb29fbTEgPC0gbG9vKG0xKQpsb29fbTIgPC0gbG9vKG0yKQoKbG9vX2NvbXBhcmUobG9vX20xLCBsb29fbTIpCmBgYAoKClRPRE8KCiAtIFBSSU9SUwogLSBPVEhFUiBDT1ZBUklBVEVTCiAtIENPTVBBUkUgTU9ERUxTIFdJVEggRElGRkVSRU5UIEJBU0lTIEZVTkNUSU9OUyBGT1IgR1AgQU5EIFNQTElORVMKIC0gRVhDRUVEQU5DRVMKIC0gTElOSyBUTyBNVEIgSU5GRUNUSU9OIFBSRVZBTEVOQ0UgREFUQSwgQU5EIE1PREVMCg==